package main

import "C"

import (
	"bytes"
	"fmt"
	"strconv"
)

func main() {}

var buffer = bytes.NewBufferString("")
var tmp byte

func isDigit(head []byte, c byte) bool {
	if len(head) == 0 && c >= '0' && c <= '9' {
		return true
	}
	if head[0] != '0' && c >= '0' && c <= '9' {
		return true
	}
	return false

}

func isHex(head []byte, c byte) bool {
	if head[0] == '0' {
		if c >= '0' && c <= '9' {
			return true
		}
		if c >= 'a' && c <= 'f' {
			return true
		}
	}
	return false

}

//export IMIsDec
func IMIsDec() int {
	if buffer.Len() == 0 {
		return 1
	}
	vec := buffer.Bytes()
	if vec[0] != '0' {
		return 1
	}
	return 0
}

//export IMVerifyChar
func IMVerifyChar(c C.char) int {
	vec := buffer.Bytes()
	b := byte(c)
	if isDigit(vec, b) || isHex(vec, b) {
		return 1
	}
	return 0
}

//export IMPushc
func IMPushc(c C.char) []*C.char {
	tmp = byte(c)
	buffer.WriteByte(tmp)
	vec := buffer.Bytes()
	//println(string(vec))
	if isDigit(vec, tmp) {
		convertToHex()
		return res[:]
	}

	if isHex(vec, tmp) {
		//println("hex to dec")
		convertToDec()
		return res[:]
	}

	return res[:]

}

var res [4]*C.char
var emptyStr = C.CString("")

func IMReset() {
	for i := range res {
		res[i] = emptyStr
	}
}

func convertToHex() {

	l := len(buffer.Bytes())
	if l == 0 {
		IMReset()
		return
	}
	val, err := strconv.ParseInt(buffer.String(), 10, 64)
	if err != nil {
		IMReset()
		return
	}

	res[0] = C.CString(fmt.Sprintf("0x%x", val))
	res[1] = C.CString(fmt.Sprintf("0X%X", val))
	res[2] = C.CString(fmt.Sprintf("%x", val))
	res[3] = C.CString(fmt.Sprintf("%X", val))
}

func convertToDec() {
	l := len(buffer.Bytes())
	if l == 0 {
		IMReset()
		return
	}

	val, err := strconv.ParseInt(buffer.String(), 16, 64)
	if err != nil {
		IMReset()
		return
	}
	//println("num:", val)
	res[0] = C.CString(strconv.FormatInt(val, 10))
	for i := 1; i < len(res); i++ {
		res[i] = res[0]
	}
}

//export IMClean
func IMClean() {
	buffer.Reset()
	IMReset()
}
